package com.dhcc.DRGsHosp.facade.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.inject.Named;

import org.openkoala.koala.commons.InvokeResult;
import org.openkoala.security.shiro.CurrentUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.dhcc.DRGsHosp.application.DrgsIndexCalApplication;
import com.dhcc.DRGsHosp.application.SystemConfigApplication;
import com.dhcc.DRGsHosp.core.domain.IndexCal;
import com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade;
import com.dhcc.DRGsHosp.facade.dto.IndexCalDTO;
import com.dhcc.DRGsHosp.facade.impl.assembler.IndexCalAssembler;
import com.dhcc.DRGsHosp.infra.util.Arith;
import com.dhcc.DRGsHosp.infra.util.DrgsIndex;
import com.dhcc.DRGsHosp.infra.util.GlobalData;
import com.dhcc.DRGsHosp.infra.util.MapSortByField;
import com.dhcc.DRGsHosp.infra.util.StringUtils;

/**
 * 
 * @ClassName: FileUploadFacadeImpl  
 * @Description ：    指标计算实现层
 * @Date: 2017年5月8日 下午2:53:07  
 * @Author LiuHongJun 
 * @Version 2.5.0 DHC-DRGs
 */
@Named("drgsFacadeImplLiuhongjun201705081701")
public class DrgsIndexCalFacadeImpl implements DrgsIndexCalFacade {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DrgsIndexCalFacadeImpl.class);
	
    @Autowired
    private DrgsIndexCalApplication  drgsIndexCalApplication;
    @Autowired
    private SystemConfigApplication  systemConfigApplication;
    

      
    /**
     *  @Description：获取院内均值
     *  @Author LiuHongJun  
     *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#avgHospIndexCal(com.dhcc.DRGsHosp.facade.dto.IndexCalDTO)
     */
	@Override
	public List<Map<String,Object>>  avgHospIndexCal(IndexCalDTO dto) {
		//定义指标代码
		List<Map<String,Object>> quotas = new LinkedList<Map<String,Object>>();
		//将时间格式化
	    dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
	    dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
        // 获取标杆定位id 
	    String stdId=getStdID(dto.getDateFrom(),dto.getDateTo());
	    //获取分组方案
	    dto.setVerRegion(getGroupScheme());
	    //没获取到分组方案
	    if(stdId==null) {
	    	return new LinkedList<>();
	    }
	    //定位具体使用哪套标杆
	    dto.setStdId(stdId);
		//当多指标时取出指标code放入list中，如果是单指标走else
		String quotaCodes = dto.getQuotaCode();
		if(StringUtils.hasLength(quotaCodes) && quotaCodes.contains(",")) {
			String codes[] = quotaCodes.split(",") ;
			for(String code: codes) {
				List<Map<String,Object>> listQuotaes = drgsIndexCalApplication.getQuotasByMoreCode(code);
				// codes 里可能的指标本身可能是个关联指标查询
				if( null != listQuotaes && listQuotaes.size() > 0) {
					for(Map<String,Object> map : listQuotaes) {
						quotas.add(map);
					}
				} else {
					Map<String, Object> map = drgsIndexCalApplication.getQuotaDetail(code);	
					if(map!=null&&map.size()>0) {
						quotas.add(map);
					}
				}
			}
		} else {
			// 关联指标查询
			List<Map<String, Object>> list = drgsIndexCalApplication.getQuotasByMoreCode(dto.getQuotaCode());
			if(!list.isEmpty()) {
				quotas=list;
			}else {
				Map<String, Object> map = drgsIndexCalApplication.getQuotaDetail(dto.getQuotaCode());
				if(!map.isEmpty()) {
					quotas.add(map);
				}
			}
		}
		List<Map<String, Object>> listMap = new LinkedList<>();
		Map<String, Map<String, Object>> resultMap=new LinkedHashMap<>();
		if(quotas.size()>1){
			IndexCalDTO qDto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
			resultMap =getDrgsAvgHospQuotaes(qDto, quotas);
		}else{
			IndexCalDTO qDto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
			 resultMap = getDrgsAvgHospQuota(qDto);
		}
		if(resultMap!=null) {
			for (Entry<String, Map<String, Object>> entry : resultMap.entrySet()) {  
				 Map<String,Object> map=entry.getValue();
				 listMap.add(map);
			}
		}
		return listMap;
	}
/**
 *  @Description：指标计算总方法
 *  @Author LiuHongJun  
 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#indexCal(java.util.Map)
 */
	@Override
	public List<Map<String,Object>> indexCal(IndexCalDTO dto) {
		//定义指标代码
		List<Map<String,Object>> quotas = new LinkedList<Map<String,Object>>();
		//将时间格式化
	    dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
	    dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
	    // 获取标杆定位id
	    String stdId=dto.getStdId();
	    if(stdId==null) {
	    	 stdId=getStdID(dto.getDateFrom(),dto.getDateTo());
	    }
	    // 获取病组版本号
	    String verCode=getVerCode(dto.getDateFrom(),dto.getDateTo());
	    //没获取到分组方案
	    if(stdId==null) {
	    	return new LinkedList<>();
	    }
	    //定位具体使用哪套标杆
	    dto.setStdId(stdId);
	    //定位病组版本号
	    dto.setVerCode(verCode);
	    //获取分组方案
	    dto.setVerRegion(getGroupScheme());	
	    dto.setManageYear(getManageYear(dto));	    
		//当多指标时取出指标code放入list中，如果是单指标走else
		String quotaCodes = dto.getQuotaCode();
		// 多指标查询
		if(StringUtils.hasLength(quotaCodes) && quotaCodes.contains(",")) {
			String codes[] = quotaCodes.split(",") ;
			for(String code: codes) {
				List<Map<String,Object>> listQuotaes = drgsIndexCalApplication.getQuotasByMoreCode(code);
				// codes 里可能的指标本身可能是个关联指标查询
				if( null != listQuotaes && listQuotaes.size() > 0) {
					for(Map<String,Object> map : listQuotaes) {
						quotas.add(map);
					}
				} else {
					Map<String, Object> map = drgsIndexCalApplication.getQuotaDetail(code);	
					if(map!=null&&map.size()>0) {
						quotas.add(map) ;
					}
				}
			}
		} else {
			// 关联指标查询
			List<Map<String, Object>> list = drgsIndexCalApplication.getQuotasByMoreCode(dto.getQuotaCode());
			if(!list.isEmpty()) {
				quotas=list;
			}else {
				Map<String, Object> map = drgsIndexCalApplication.getQuotaDetail(dto.getQuotaCode());
				if(map!=null&&map.size()>0) {
					quotas.add(map) ;
				}
			}
		}
		
		List<Map<String, Object>> mapList = new LinkedList<>();
		Map<String, Map<String, Object>> resultMap=new LinkedHashMap<>();
		Map<String, Map<String, Object>> resultMapcc=new LinkedHashMap<>();
		// only1 代表只查询比较值
		if(!"only1".equals(dto.getIsGetCc())){
			if(quotas.size()>1){
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				resultMap = getDrgsQuotaes(qdto, quotas);//多指标
			}else{
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				resultMap = getDrgsQuota(qdto,quotas);//单指标
			}
		} else if("only1".equals(dto.getIsGetCc())){ // 仅获取标杆值，用于付费病组
			IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
			return queryBenchmarkValue(qdto,quotas) ;
		}
		
		//*****************************以下根据比较对象不同获取不同的比较数据,根据前台返回的是否获取比较值来提高查询效率****************************************
		//根据比较类型和日期获取同期或者上期的日期
		if("1".equals(dto.getIsGetCc())){
			if("year".equals(dto.getCompareType())){//同比（直接取得t_anstd中的标杆参与计算）
				String dateFromCc = DrgsIndex.getDateFromCc(dto.getDateFrom(),dto.getCompareType());
				String dateToCc = DrgsIndex.getDateFromCc(dto.getDateTo(),dto.getCompareType());
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				qdto.setDateFrom(dateFromCc);
				qdto.setDateTo(dateToCc);
				if(quotas.size()>1){
					resultMapcc = getDrgsQuotaes(qdto, quotas);
				}else{
					resultMapcc =getDrgsQuota(qdto,quotas);
				}
			}else if("month".equals(dto.getCompareType())){//环比（直接取得t_anstd中的标杆参与计算）
				String dateFromCc = DrgsIndex.getDateFromCc(dto.getDateFrom(),dto.getCompareType());
				String dateToCc = DrgsIndex.getDateFromCc(dto.getDateTo(),dto.getCompareType());
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				qdto.setDateFrom(dateFromCc);
				qdto.setDateTo(dateToCc);
				if(quotas.size()>1){
					resultMapcc = getDrgsQuotaes(qdto, quotas);
				}else{
					resultMapcc =getDrgsQuota(qdto,quotas);
				}
			}else if("manage".equals(dto.getCompareType())){//绩效比（提前维护好的各个对象的各标杆值，不用DRG的标杆计算）
				//获取目前维护的指标绩效和标杆比值
				List<String> list=drgsIndexCalApplication.getManagerQuotaCode(dto.getManageYear(),dto.getpType(),dto.getMsCode());
				String sqlStr = drgsIndexCalApplication.getSqlByQuotaCode("QuotaManage");		
				try{
					// 获取要计算的描述和编码列表
					Map<String, Map<String, Object>> rMap=new LinkedHashMap<>();
					String sqlBase = drgsIndexCalApplication.getSqlByQuotaCode("Base");
					dto.setSqlStr(sqlBase);
					List<Object[]> resultList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto),"Base");
					// 存放结果集
					for (Object[] objs : resultList) {
						Map<String, Object> map = new HashMap<>();
						map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
						map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
						rMap.put(objs[1]+"",map);
					}
					//多指标
					if(quotas.size()>1){
						ExecutorService indexPool = Executors.newFixedThreadPool(quotas.size());
						List<Future<Map<String, Map<String, Object>>>> listf = new ArrayList<>();
						for(int i=0; i<quotas.size(); i++){
							IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
							String quotaCode = quotas.get(i).get("QUOTA_CODE")!=null?quotas.get(i).get("QUOTA_CODE").toString():null;
							String unit = quotas.get(i).get("UNIT")!=null?quotas.get(i).get("UNIT").toString():null;
							//判断该指标是否为配置过的绩效指标
							if(quotaCode!=null&&unit!=null&&!list.isEmpty()&&list.contains(quotaCode)){
								qdto.setSqlStr(sqlStr);	
								qdto.setUnit(unit);
								qdto.setQuotaCode(quotaCode);
								ManagerQuotaCallable c = new ManagerQuotaCallable(qdto);
								listf.add(indexPool.submit(c));
							}
						}
						indexPool.shutdown();
						getCompareListfToMap(listf,rMap,resultMapcc);							
					}else{//单指标
						Map<String, Object> qMap=quotas.get(0);			
						String quotaCode = qMap.get("QUOTA_CODE")==null?null:qMap.get("QUOTA_CODE").toString();
						// 获取指标精度
						int unit =  qMap.get("UNIT")==null?0:Integer.valueOf(qMap.get("UNIT").toString());
						//判断该指标是否为配置过的绩效指标
						if(quotaCode!=null&&sqlStr!=null&&!list.isEmpty()&&list.contains(quotaCode)){
							IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
							qdto.setSqlStr(sqlStr);
							List<Object[]> listcc  = drgsIndexCalApplication.getDrgsManagerIndex(IndexCalAssembler.toEntity(qdto),quotaCode);
							if(listcc.size()>0){
								for(Object[] objs: listcc){
									Map<String, Object> map = new HashMap<>();
									Double value = null;
									if(objs[1]!=null){
										value =Arith.div(Double.parseDouble(objs[1].toString()), 1,unit);
									}
									if(objs[0]!=null){
										map.put("ccode",objs[0]==null?"notcode":objs[0].toString());
										if(("TotalFee".equals(qdto.getQuotaCode()) || "DrugFee".equals(qdto.getQuotaCode()))&& value!=null){
											map.put("QuotaValue", value/10000);
										}else{
											map.put("QuotaValue", value);
										}
									}
									resultMapcc.put(objs[0]==null?"":objs[0].toString(), map);
								}
							}
						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
			}else if("std".equals(dto.getCompareType())){//标杆比
				String sqlStr = drgsIndexCalApplication.getSqlByQuotaCode("StdQuota");
				try{
					// 获取要计算的描述和编码列表
					Map<String, Map<String, Object>> rMap=new LinkedHashMap<>();
					String sqlBase = drgsIndexCalApplication.getSqlByQuotaCode("Base");
					dto.setSqlStr(sqlBase);
					List<Object[]> resultList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto),"Base");
					// 存放结果集
					for (Object[] objs : resultList) {
						Map<String, Object> map = new HashMap<>();
						map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
						map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
						rMap.put(objs[1]+"",map);
					}
					//多指标计算
					if(quotas.size()>1){
						ExecutorService indexPool = Executors.newFixedThreadPool(quotas.size());
						List<Future<Map<String, Map<String, Object>>>> listf = new ArrayList<>();
						for(int i=0; i<quotas.size(); i++){
							IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
							String quotaCode = quotas.get(i).get("QUOTA_CODE")!=null?quotas.get(i).get("QUOTA_CODE").toString():null;
							String unit = quotas.get(i).get("UNIT")!=null?quotas.get(i).get("UNIT").toString():"0";
							//判断该指标是否为配置过的绩效指标
							if(quotaCode!=null&&unit!=null){
								qdto.setSqlStr(sqlStr);	
								qdto.setUnit(unit);
								qdto.setQuotaCode(quotaCode);
								StdQuotaCallable c = new StdQuotaCallable(qdto);
								listf.add(indexPool.submit(c));
							}
						}
						indexPool.shutdown();
						getCompareListfToMap(listf,rMap,resultMapcc);						
					}else{//单指标计算
							IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
							Map<String, Object> qMap=quotas.get(0);			
							String quotaCode = qMap.get("QUOTA_CODE")==null?null:qMap.get("QUOTA_CODE").toString();
							// 获取指标精度
							int unit =  qMap.get("UNIT")==null?0:Integer.valueOf(qMap.get("UNIT").toString());
							List<Object[]> resultListcc = null;
							qdto.setSqlStr(sqlStr);
							resultListcc = drgsIndexCalApplication.getDrgsStdIndex(IndexCalAssembler.toEntity(qdto),quotaCode);
							if(resultListcc.size()>0){
								for(Object[] objs: resultListcc){
									Map<String, Object> map = new HashMap<>();
									Double value = null;
									if(objs[1]!=null){
										value =Arith.div(Double.parseDouble(objs[1].toString()), 1,unit);	
									}
									if(objs[0]!=null){
										map.put("ccode", objs[0]==null?"notcode":objs[0].toString());
										if(("TotalFee".equals(qdto.getQuotaCode())||"DrugFee".equals(qdto.getQuotaCode())) && value!=null){
											map.put("QuotaValue", value/10000);
										}else{
											map.put("QuotaValue", value);
										}
									}
									resultMapcc.put(objs[0]==null?"":objs[0].toString(), map);
								}
							}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
			//计算院内均值
			}else if("hosp".equals(dto.getCompareType())){
				//**********全院均值其他标识记得清空**********************//
				//是否重点病组 是否付费病组标识清空 
				dto.setIsPayGroup("");
				dto.setIsKeyDisGroup("");
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				if(quotas.size()>1){
					Map<String,Object> m = new HashMap<String,Object>();
					m.put("QUOTA_CODE","DRGCount");
					if(quotas.contains(m)){
						quotas.remove(m);
						Map<String,Object> mo = new HashMap<String,Object>();
						mo.put("QUOTA_CODE","DRGCount_t");//理论drg组数
						quotas.add(mo);
					}
					resultMapcc =getDrgsAvgHospQuotaes(qdto, quotas);
				}else{
					resultMapcc = getDrgsAvgHospQuota(qdto);
				}
			}
			//拼接两个map,并压入mapList
			 if("hosp".equals(dto.getCompareType())) {
					for (Entry<String, Map<String, Object>> entry : resultMap.entrySet()) {  
						 Map<String,Object> map=entry.getValue();
						 Map<String,Object> mapcc=resultMapcc.get("1");
						 DrgsIndex.mergeAvgHospResultMap(map,mapcc);
						 mapList.add(map);
					}
			 }else {
					for (Entry<String, Map<String, Object>> entry : resultMap.entrySet()) {  
						 String sKey= entry.getKey();
						 Map<String,Object> map=entry.getValue();
						 Map<String,Object> mapcc=resultMapcc.get(sKey);
						 DrgsIndex.mergeResultMap(map,mapcc);
						 mapList.add(map);
					}
			 }
		}else {
			if(resultMap!=null) {
				for (Entry<String, Map<String, Object>> entry : resultMap.entrySet()) {  
					 Map<String,Object> map=entry.getValue();
					 mapList.add(map);
				}
			}		
		}
		return mapList;
	}
	
	/**
	 *  查询标杆值
	 *  queryBenchmarkValue.  
	 *  @Description：
	 *  @Author ChenHanlin
	 *  @param dto 
	 *  @Date:2018年5月5日上午10:09:53
	 */
	private List<Map<String, Object>> queryBenchmarkValue(IndexCalDTO dto,List<Map<String,Object>> quotas) {
		// 指标编码list
		List<String> strList = new ArrayList<>() ;
		for(Map<String,Object> mapQ:quotas){
			strList.add(mapQ.get("QUOTA_CODE")+"") ;
		}
		// 指标编码数组
		String[] quotaCodes= strList.toArray(new String[strList.size()]);
		List<Map<String, Object>> mapList = new LinkedList<>();
		StringBuffer strb = new StringBuffer() ;
		strb.append(" select * from (select pardrg_code ccode, drg.drg_desc ddesc,parquota_code, manage_benchmark from drgs.t_managesummarydtl mdtl \n ") ;
		strb.append(" left join drgs.t_drgs drg on mdtl.pardrg_code = drg.drg_code and drg.ver_code = :verCode \n ") ;
		strb.append(" where mdtl.par_ms_code = :ms_code and mdtl.std_year = :manageYear \n ") ;
		strb.append(" and mdtl.pardrg_code = :drgCode ) \n ") ;
		strb.append(" pivot (sum(manage_benchmark) for parquota_code \n ") ;
		strb.append(" in ("+StringUtils.convertArrayToQuoteString(quotaCodes)+")) \n ") ;
		strb.append(" \n ") ;
		dto.setSqlStr(strb.toString());
		int unit =  quotas.get(0).get("UNIT")==null?0:Integer.valueOf(quotas.get(0).get("UNIT").toString());
		List<Object[]> resultList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto), null);
		for (Object[] objs : resultList) {
			Map<String, Object> map = new HashMap<>();
			map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
			map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
			int i= 2 ;
			for(String quotaCode:strList){
				map.put(quotaCode+"cc",objs[i]==null?null:(Arith.div(Double.parseDouble(objs[i].toString()),1,unit)));
				i++ ;
			}
			mapList.add(map);
		}
		return mapList ;
	}
	
	/**
	 *  @Description：获取标杆定位id
	 *  @Author lhj 
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getStdID(java.lang.String, java.lang.String)
	 */
	@Override
	public String getStdID(String dateFrom, String dateTo) {
		dateFrom=DrgsIndex.formateDateFrom(dateFrom);
		dateTo=DrgsIndex.formateDateTo(dateTo);
		String roleCode=DrgsIndex.getRoleCode();
		String userCode=CurrentUser.getUserAccount();
		if(userCode==null) {
			//接口走公共方法
			 userCode="yizheng";
		}
	    //获取分组分案cn或bj 和标杆类型 
		String mouldeId="groupScheme_"+userCode+"_"+roleCode;
		String groupSchemeBenchType = systemConfigApplication.getSystemGroupScheme(mouldeId,userCode, roleCode);
		if(StringUtils.hasLength(groupSchemeBenchType)) {
			String gbStr[]=groupSchemeBenchType.split("θ");	
			//获取分组器版本号
			List<Map<String, Object>> list=drgsIndexCalApplication.checkVerVersion(gbStr[0],dateFrom,dateTo);
			String verCode="";
			if(!list.isEmpty()&&list.get(0).get("VER_CODE")!=null){
				verCode=list.get(0).get("VER_CODE").toString();
			}
			//获取标杆年分
			String stdYear=drgsIndexCalApplication.getStdYear(gbStr[1],verCode,dateTo.substring(0, 4));
			return verCode+"_"+gbStr[1]+"_"+stdYear;
		}else {
			 return null;
		} 
	}
	/**
	 *  @desp  ：获取当前分组版本号
	 *  @Author： lhj
	 *  @param dateFrom 开始时间
	 *  @param dateTo 结束时间
	 *  @return
	 *  @Date  :2018年1月29日上午9:04:16
	 */
	@Override
	public String getVerCode(String dateFrom, String dateTo) {
		dateFrom=DrgsIndex.formateDateFrom(dateFrom);
		dateTo=DrgsIndex.formateDateFrom(dateTo);
		String roleCode=DrgsIndex.getRoleCode();
		String userCode=CurrentUser.getUserAccount();
		if(userCode==null) {
			//接口走公共方法
			 userCode="yizheng";
		}
	    //获取分组分案cn或bj 和标杆类型 
		String mouldeId="groupScheme_"+userCode+"_"+roleCode;
		String groupSchemeBenchType = systemConfigApplication.getSystemGroupScheme(mouldeId,userCode, roleCode);
		if(StringUtils.hasLength(groupSchemeBenchType)) {
			String gbStr[]=groupSchemeBenchType.split("θ");	
			//获取分组器版本号
			List<Map<String, Object>> list=drgsIndexCalApplication.checkVerVersion(gbStr[0],dateFrom,dateTo);
			String verCode="";
			if(!list.isEmpty()&&list.get(0).get("VER_CODE")!=null){
				verCode=list.get(0).get("VER_CODE").toString();
			}
			return verCode;
		}else {
			 return null;
		} 
	}
	/**
	 * 
	 *  @desp  ：单指标查询
	 *  @Author： lhj
	 *  @param dto
	 * @param quotas 
	 *  @return map<对象code，map<对象，值>
	 *  @Date  :2017年12月14日下午8:15:28
	 */
    private Map<String, Map<String, Object>> getDrgsQuota(IndexCalDTO dto, List<Map<String, Object>> quotas) {
		Map<String, Map<String, Object>> rMap=new LinkedHashMap<>();
		try {
			String quotaCode = quotas.get(0).get("QUOTA_CODE")==null?null:quotas.get(0).get("QUOTA_CODE").toString();
			int unit =  quotas.get(0).get("UNIT")==null?0:Integer.valueOf(quotas.get(0).get("UNIT").toString());
			String[] codes=new String[3];
			if("TotalScore".equals(quotaCode)){
				List<Map<String, Object>> quotaScore=new LinkedList<Map<String,Object>>();
				codes[0]="QualityScore";
				codes[1]="EfficiencyScore";
				codes[2]="CapacityScore";
				for(String code: codes) {
					List<Map<String,Object>> listQuotaes = drgsIndexCalApplication.getQuotasByMoreCode(code);
					// codes 里可能的指标本身可能是个关联指标查询
					if( null != listQuotaes && listQuotaes.size() > 0) {
						for(Map<String,Object> map : listQuotaes) {
							quotaScore.add(map);
						}
					} else {
						Map<String, Object> map = drgsIndexCalApplication.getQuotaDetail(code);	
						if(map!=null&&map.size()>0) {
							quotaScore.add(map) ;
						}
					}
				}
				Map<String, Map<String, Object>> newMap=getDrgsQuotaes(dto,quotaScore);
				Double sets[]=findTotalScoreConfig();
				for (Entry<String, Map<String, Object>> entry : newMap.entrySet()) {
					Map<String, Object> nMap=new HashMap<>();
					 String sKey= entry.getKey();
					 Map<String,Object> map=entry.getValue();
					 double quality=Double.valueOf(map.get("QualityScore")==null?"0":map.get("QualityScore").toString());
					 double effic=Double.valueOf(map.get("EfficiencyScore")==null?"0":map.get("EfficiencyScore").toString());
					 double cap=Double.valueOf(map.get("CapacityScore")==null?"0":map.get("CapacityScore").toString());
					 Double value=Arith.div(sets[0]*cap+sets[1]*quality+sets[2]*effic,1,unit) ;
					 nMap.put("ccode", sKey);
					 nMap.put("ddesc", map.get("ddesc"));
					 nMap.put("QuotaValue", value);
					 rMap.put(sKey, nMap);
				}
				return rMap; 
			}
			
			if("1".equals(dto.getUseBaseQuota())){
				// 获取要计算的描述和编码列表
				dto.setSqlStr(drgsIndexCalApplication.getSqlByQuotaCode("Base"));
				List<Object[]> resultList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto),"Base");
				// 存放结果集
				for (Object[] objs : resultList) {
					Map<String, Object> map = new HashMap<>();
					map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
					map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
					rMap.put(objs[1]+"",map);
				}
			}
			Map<String, Object> qMap=quotas.get(0);			
			quotaCode = qMap.get("QUOTA_CODE")==null?null:qMap.get("QUOTA_CODE").toString();
			// 获取指标精度
			 unit =  qMap.get("UNIT")==null?0:Integer.valueOf(qMap.get("UNIT").toString());
			// 获取计算指标sql
			String sqlStr =  qMap.get("SELECT_SQL")==null?null:qMap.get("SELECT_SQL").toString();
			if(quotaCode!=null&&sqlStr!=null) {
				// 超标病例
				sqlStr = DrgsIndex.replaceExcess(dto.getCompareType(), quotaCode, dto.getpType(), sqlStr);
				dto.setSqlStr(sqlStr);
				List<Object[]> rList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto), quotaCode);
				// 匹配数字的正则表达式
				Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+");  
				for (Object[] objs : rList) {
					Map<String, Object> map = new HashMap<>();
					map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
					map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
					if (objs.length > 2) {
						if (objs[2] != null) {
							// 判断是否是数字
							Matcher isNum = pattern.matcher(objs[2].toString().trim());
							if(isNum.matches()) {
								Double value=Arith.div(Double.parseDouble(objs[2].toString()), 1,unit);
								map.put("QuotaValue", value);
							} else {
								map.put("QuotaValue", objs[2].toString());
							}
						} else {
							map.put("QuotaValue", 0);
						}
					}
					rMap.put(objs[1]+"", map);
				}
			}
		} catch (Exception e) {
			rMap=new HashMap<>();
			LOGGER.error(e.getMessage());
			e.printStackTrace();
			return rMap;
		}
		return rMap;
	}
	/**
	 *  @desp  ：多指标查询
	 *  @Author： lhj
	 *  @param qdto
	 *  @param quotas
	 *  @return  map<对象code，map<对象，值>
	 *  @Date  :2017年12月15日上午8:51:56
	 */
	private Map<String, Map<String, Object>> getDrgsQuotaes(IndexCalDTO dto, List<Map<String, Object>> quotas) {
		Map<String,Map<String, Object>> rMap = new LinkedHashMap<>();
		try {
			if("1".equals(dto.getUseBaseQuota())){
				String quotaCode = "Base";
				// 获取要计算的描述和编码列表
				String sqlStr = drgsIndexCalApplication.getSqlByQuotaCode(quotaCode);
				dto.setSqlStr(sqlStr);
				List<Object[]> resultList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto),quotaCode);
				// 存放结果集
				for (Object[] objs : resultList) {
					Map<String, Object> map = new HashMap<>();
					map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
					map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
					rMap.put(objs[1]+"",map);
				}
			}
			
			ExecutorService indexPool = Executors.newFixedThreadPool(quotas.size());
			List<Future<Map<String, Map<String, Object>>>> listf = new ArrayList<>();
			// 计算多指标
			for (int i = 0; i < quotas.size(); i++) {
				IndexCalDTO qdto = (IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				String quotaCode = quotas.get(i).get("QUOTA_CODE") != null ? quotas.get(i).get("QUOTA_CODE").toString() : null;
				// 获取指标精度
				String unit = quotas.get(i).get("UNIT") != null ? quotas.get(i).get("UNIT").toString() : "0";
				// 获取计算指标SQL
				String sqlStr =quotas.get(i).get("SELECT_SQL") != null ? quotas.get(i).get("SELECT_SQL").toString() : null;
				if(quotaCode!=null&& sqlStr!=null) {
					// 超标病例替换
					sqlStr = DrgsIndex.replaceExcess(qdto.getCompareType(), quotaCode, qdto.getpType(), sqlStr);
					qdto.setSqlStr(sqlStr);
					qdto.setQuotaCode(quotaCode);
					qdto.setUnit(unit);
					// 启动多线程
					QuotaCallable c = new QuotaCallable(qdto);
					listf.add(indexPool.submit(c));
				}
			}
			indexPool.shutdown();
			getListfToMap(listf,rMap);
		}catch(Exception e) {		
			LOGGER.error(e.getMessage());
			rMap=new HashMap<>();
			e.printStackTrace();
			return rMap;
		}
		return rMap;
	}
	/**
	 *  @desp  ：单指标全院均值计算
	 *  @Author： lhj
	 *  @param dto
	 *  @return
	 *  @Date  :2017年12月16日下午7:10:01
	 */
	 private Map<String, Map<String, Object>> getDrgsAvgHospQuota(IndexCalDTO dto) {
		   Map<String, Map<String, Object>> rMap=new HashMap<>();
		 try {
				 IndexCal index=new IndexCal();
				String quotaCode=dto.getQuotaCode();			
				index.setReplaceQuotaCode(quotaCode);
				index.setMonitorType(dto.getMonitorType());
				//调用方法替换指标代码，做特殊指标代码的映射
				DrgsIndex.replacementQuotaCode(index);			
				quotaCode=index.getReplaceQuotaCode();
				dto.setMonitorType(index.getMonitorType());
				//获取指标精度
				int unit = Integer.valueOf(drgsIndexCalApplication.getUnitByQuotaCode(quotaCode));
				//获取计算指标sql
				String sqlStr=drgsIndexCalApplication.getSqlByQuotaCode(quotaCode);
				dto.setSqlStr(sqlStr);
				List<Object[]> list = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto), quotaCode);
				if (!list.isEmpty()) {
					Object[] objs = list.get(0);
					Map<String, Object> map = new HashMap<>();
					map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
					map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
					if (objs.length > 2) {
						if (objs[2] != null) {
							Double value=Arith.div(Double.parseDouble(objs[2].toString()), 1,unit);
							map.put("QuotaValue", value);
						} else {
							map.put("QuotaValue", 0);
						}
					} else {
						map.put("QuotaValue", 0);
					}
					rMap.put(objs[1]==null?"":objs[1].toString(), map);
				}
			}catch(Exception e) {
				rMap=new HashMap<>();
				LOGGER.error(e.getMessage());
				e.printStackTrace();
				return rMap;
			}
			return rMap;
	 }
	/**
	* 
	*  @desp  ：多指标院内均值线程
	*  @Author： lhj
	*  @param dto
	*  @param quotas
	*  @return
	*  @Date  :2017年12月16日下午7:37:20
	*/
	private Map<String, Map<String, Object>> getDrgsAvgHospQuotaes(IndexCalDTO qdto, List<Map<String, Object>> quotas) {
		Map<String, Map<String, Object>> rMap=new HashMap<>();
		try {
			Map<String, Object> mapo=new HashMap<>();
			mapo.put("ccode", "1");
			mapo.put("ddesc", "全院");
			rMap.put("1",mapo);
			ExecutorService indexPool = Executors.newFixedThreadPool(8);
			List<Future<Map<String, Map<String, Object>>>> listf = new ArrayList<>();
			for(int i=0; i<quotas.size(); i++){
				IndexCalDTO dto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(qdto);
				IndexCal index=new IndexCal();
				String quotaCode = quotas.get(i).get("QUOTA_CODE")!=null?quotas.get(i).get("QUOTA_CODE").toString():"";				
				index.setReplaceQuotaCode(quotaCode);
				index.setMonitorType(dto.getMonitorType());
				//调用方法替换指标代码，做特殊指标代码的映射
				DrgsIndex.replacementQuotaCode(index);				
				//获取映射后的指标代码
				quotaCode=index.getReplaceQuotaCode();
				dto.setMonitorType(index.getMonitorType());
				//获取并压入特殊指标映射
				dto.setQuotaMap(index.getQuotaMap());
				//获取指标精度
				String unit = drgsIndexCalApplication.getUnitByQuotaCode(quotaCode);
				//获取计算指标sql
				String	sqlStr=drgsIndexCalApplication.getSqlByQuotaCode(quotaCode);
				dto.setSqlStr(sqlStr);
				dto.setUnit(unit);
				dto.setQuotaCode(quotaCode);
				HospQuotaCallable c = new HospQuotaCallable(dto);
				listf.add(indexPool.submit(c));
			}
			indexPool.shutdown();
			getListfToMap(listf,rMap);
		} catch (Exception e) {
			rMap=new HashMap<>();
			LOGGER.error(e.getMessage());
			e.printStackTrace();
			return rMap;
		}				
		return rMap;	
	}
	/**
	 *  @desp  ：从listf里取出对象放到map集合中
	 *  @Author： lhj
	 *  @param listf
	 *  @param rMap
	 *  @Date  :2017年12月20日上午11:57:08
	 */
	private void getListfToMap(List<Future<Map<String, Map<String, Object>>>> listf,
			Map<String, Map<String, Object>> rMap) {
		try {
			for (Future<Map<String, Map<String, Object>>> fr : listf) {
				Map<String, Map<String, Object>> mapn = fr.get();
				if(rMap.isEmpty()){
					for(Entry<String, Map<String, Object>> entry : mapn.entrySet()){
						rMap.put(entry.getKey(), entry.getValue());
					}
					continue;
				}
				Map<String, Map<String, Object>> forMap = (Map<String, Map<String, Object>>) DrgsIndex.copyPropertiesObj(rMap);
				for (Entry<String, Map<String, Object>> entry : forMap.entrySet()) {
					String sKey = entry.getKey();
					Map<String, Object> map = entry.getValue();
					Map<String, Object> mapcc = mapn.get(sKey);
					if (map != null && mapcc != null) {
						map.putAll(mapcc);
					}
					rMap.put(sKey, map);
				}
			}
			System.out.println();
		} catch (Exception e) {
			LOGGER.error(e.getMessage());
			e.printStackTrace();
		}
	}
	/**
	 * 
	 *  @desp  ：绩效比标杆比--listf里取出对象放到map集合中
	 *  @Author： lhj
	 *  @param listf
	 *  @param rMap
	 *  @param resultMapcc
	 *  @Date  :2017年12月20日下午12:02:53
	 */
	private void getCompareListfToMap(List<Future<Map<String, Map<String, Object>>>> listf,
		Map<String, Map<String, Object>> rMap, Map<String, Map<String, Object>> resultMapcc) {
		try {
			for (Future<Map<String, Map<String, Object>>> fr : listf) {
				Map<String, Map<String, Object>> mapn = fr.get();
				for (Entry<String, Map<String, Object>> entry : rMap.entrySet()) {
					String sKey = entry.getKey();
					Map<String, Object> map = entry.getValue();
					Map<String, Object> mapcc = mapn.get(sKey);
					if (map != null && mapcc != null) {
						map.putAll(mapcc);
					}
					resultMapcc.put(sKey, map);
				}
			}
		} catch (Exception e) {
			LOGGER.error(e.getMessage());
			e.printStackTrace();
		}

	}
	/**
	 * @desp     ：  线程计算指标  
	 * @Author   ：lhj  
	 * @ClassName: QuotaCallable  
	 * @Date     : 2017年12月15日 下午4:15:37  
	 * @Version  ：3.0.0 DHC.DRGs
	 */
	private class QuotaCallable implements Callable<Map<String, Map<String, Object>>> {
		private IndexCalDTO dto;
		QuotaCallable(IndexCalDTO dto) {
			this.dto = dto;
		}
		@Override
		public Map<String, Map<String, Object>> call() {
			Map<String, Map<String, Object>> rMap=new HashMap<>();
			try {
				String quotaCode=dto.getQuotaCode();
				List<Object[]> resultList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto), dto.getQuotaCode());
				// 匹配数字的正则表达式
				Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+");   
				for(Object[] objs: resultList){
					Map<String, Object> map = new HashMap<>();
					map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
					map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
					if(objs[2]!=null){
						// 判断是否是数字
						Matcher isNum = pattern.matcher(objs[2].toString().trim());
						if(isNum.matches()) {
							int unit=Integer.valueOf(dto.getUnit());
							Double value =Arith.div(Double.parseDouble(objs[2].toString()), 1,unit);
							map.put(quotaCode, value);
						} else {
							map.put(quotaCode, objs[2].toString());
						}
					}else{
						map.put(quotaCode, 0);
					}
					rMap.put(objs[1]+"", map);
				}			
			} catch (Exception e) {
				rMap=new HashMap<>();
				LOGGER.error(e.getMessage());
				e.printStackTrace();
				return rMap;
			}
			return rMap;
		}
	}
	/**
	 * @desp     ：标杆比多指标    
	 * @Author   ：lhj  
	 * @ClassName: StdQuotaCallable  
	 * @Date     : 2018年1月8日 上午10:34:19  
	 * @Version  ：3.0.0 DHC.DRGs
	 */
	private class StdQuotaCallable implements Callable<Map<String, Map<String, Object>>> {
		private IndexCalDTO dto;
		StdQuotaCallable(IndexCalDTO dto) {
			this.dto = dto;
		}
		@Override
		public Map<String, Map<String, Object>> call() {
			Map<String, Map<String, Object>> rMap = new HashMap<>();
			try {
				String quotaCode = dto.getQuotaCode();
				int unit = Integer.valueOf(dto.getUnit());
				List<Object[]> listcc = drgsIndexCalApplication.getDrgsStdIndex(IndexCalAssembler.toEntity(dto),
						quotaCode);
				if (listcc.size() > 0) {
					for (Object[] objs : listcc) {
						Map<String, Object> map = new HashMap<>();
						Double value = null;
						if (objs[1] != null) {
							value = Arith.div(Double.parseDouble(objs[1].toString()), 1,unit);   
						}
						if (objs[0] != null) {
							map.put("ccode", objs[0] == null ? "" : objs[0].toString());
							if (("TotalFee".equals(quotaCode) || "DrugFee".equals(quotaCode))&& value!=null) {
								map.put(quotaCode, Arith.div(Double.parseDouble(objs[1].toString())/10000, 1,unit));
							} else {
								map.put(quotaCode, value);
							}
						}
						rMap.put(objs[0] == null ? "" : objs[0].toString(), map);
					}
				}
			} catch (Exception e) {
				rMap = new HashMap<>();
				LOGGER.error(e.getMessage());
				e.printStackTrace();
				return rMap;
			}
			return rMap;
		}
	}
	
	/**
	 * @desp     ：    绩效比-多指标计算线程
	 * @Author   ：lhj  
	 * @ClassName: ManagerQuotaCallable  
	 * @Date     : 2017年12月20日 上午10:02:43  
	 * @Version  ：3.0.0 DHC.DRGs
	 */
	private class ManagerQuotaCallable implements Callable<Map<String, Map<String, Object>>> {
		private IndexCalDTO dto;
		ManagerQuotaCallable(IndexCalDTO dto) {
			this.dto = dto;
		}
		@Override
		public Map<String, Map<String, Object>> call() {
			Map<String, Map<String, Object>> rMap = new HashMap<>();
			try {
				String quotaCode = dto.getQuotaCode();
				String unit = dto.getUnit();
				List<Object[]> listcc = drgsIndexCalApplication.getDrgsManagerIndex(IndexCalAssembler.toEntity(dto),
						quotaCode);
				if (listcc.size() > 0) {
					for (Object[] objs : listcc) {
						Map<String, Object> map = new HashMap<>();
						Double value = null;
						if (objs[1] != null) {
							value = Double.parseDouble(
									String.format("%." + unit + "f", Double.parseDouble(objs[1].toString())));
						}
						if (objs[0] != null) {
							map.put("ccode", objs[0] == null ? "" : objs[0].toString());
							if (("TotalFee".equals(quotaCode) || "DrugFee".equals(quotaCode))&&value!=null) {
								map.put(quotaCode, value / 10000);
							} else {
								map.put(quotaCode, value);
							}
						}
						rMap.put(objs[0] == null ? "" : objs[0].toString(), map);
					}
				}
			} catch (Exception e) {
				rMap = new HashMap<>();
				LOGGER.error(e.getMessage());
				e.printStackTrace();
				return rMap;
			}
			return rMap;
		}
	}
	/**
	 * @desp     ：  多指标-院内均值线程  
	 * @Author   ：lhj  
	 * @ClassName: HospQuotaCallable  
	 * @Date     : 2017年12月16日 下午8:17:08  
	 * @Version  ：3.0.0 DHC.DRGs
	 */
	private class HospQuotaCallable implements Callable<Map<String, Map<String, Object>>> {
		private IndexCalDTO dto;
		HospQuotaCallable(IndexCalDTO dto) {
			this.dto = dto;
		}
		@Override
		public Map<String, Map<String, Object>> call() {
			Map<String, Map<String, Object>> rMap = new HashMap<>();
			try {
				String quotaCode = dto.getQuotaCode();
				List<Object[]> resultList = drgsIndexCalApplication.getDrgsIndex(IndexCalAssembler.toEntity(dto), quotaCode);
				Map<String, Object> quotaMap = dto.getQuotaMap();// 获取指标映射
				int unit=dto.getUnit()==null?0:Integer.valueOf(dto.getUnit());
				// 匹配数字的正则表达式
				Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+"); 
				for (Object[] objs : resultList) {
					Map<String, Object> map = new HashMap<>();
					map = new HashMap<>();
					map.put("ccode", objs[1]==null?"notcode":objs[1].toString());
					map.put("ddesc", objs[0]==null?"未维护编码":objs[0].toString());
					if (objs[2] != null) {
						Matcher isNum = pattern.matcher(objs[2].toString().trim());
						// 判断是否是数字
						if(isNum.matches()) {
							Double value =Arith.div(Double.parseDouble(objs[2].toString()), 1,unit);
							map.put(quotaMap.get(quotaCode) + "", value);
						} else {
							map.put(quotaMap.get(quotaCode) + "", objs[2].toString());
						}
					} else {
						map.put(quotaMap.get(quotaCode) + "", 0);
					}
					rMap.put("1", map);
				}
			} catch (Exception e) {
				rMap = new HashMap<>();
				LOGGER.error(e.getMessage());
				e.printStackTrace();
				return rMap;
			}
			return rMap;
		}
	}
	
	
	
	
	/**
	 * 
	 *  findTotalScoreConfig.  
	 *  @Description：综合得分配置参数
	 *  @Author LiuHongjun
	 *  @param dto 
	 *  @Date:2017年8月4日下午10:14:21
	 */
	private Double[] findTotalScoreConfig() {
		String totalScore=GlobalData.sysConfig.get("TOTALSCORE");
		if(StringUtils.hasLength(totalScore)&&totalScore.split("θ").length==3){
			String[] sets=totalScore.split("θ");
			Double[] strd=new Double[3];
			strd[0]=Double.valueOf(sets[0]);
			strd[1]=Double.valueOf(sets[1]);
			strd[2]=Double.valueOf(sets[2]);
			return strd;
		}else{
			Double[] strs=new Double[]{1.0,1.0,1.0};
			return strs;
		}
	}
	

	/**
	 * 
	 *  @Description：有本年度返回本年，没有返回最新
	 *  @Author LiuHongJun  
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getManageYear(com.dhcc.DRGsHosp.facade.dto.IndexCalDTO)
	 */
	@Override
	public String getManageYear(IndexCalDTO dto) {
	return drgsIndexCalApplication.getRecentlyManageYear(dto.getDateTo().substring(0,4),dto.getMsCode(),dto.getMonitorType());
	}
	/**
	 * 
	 *  @Description：获取病例明细
	 *  @Author LiuHongJun  
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#findCaseList(com.dhcc.DRGsHosp.facade.dto.IndexCalDTO, java.lang.Boolean, int, int, int)
	 */
	@Override
	public InvokeResult findCaseList(IndexCalDTO dto, Boolean isAllUsers, int page, int pageSize, int sEcho, int caseTotalCount,String orderColumn,String orderMethod) { 
	    Map<String,Object> caseListResultMaps = new HashMap<String, Object>();
	    caseListResultMaps.put("sEcho",sEcho);	    
		//将时间格式化
	    dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
	    dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));	    
	    //获取管理目标和标杆的年份
	    String stdId=getStdID(dto.getDateFrom(),dto.getDateTo());
	    dto.setStdId(stdId);//标杆定位iD
	    String groupShcme=getGroupScheme();
	    dto.setVerRegion(groupShcme);//分组方案
	    dto.setManageYear(getManageYear(dto));
        if (StringUtils.hasLength(dto.getQuotaCode()) && GlobalData.caseLinkCondition.containsKey(dto.getQuotaCode())) {
            String condition =GlobalData.caseLinkCondition.get(dto.getQuotaCode());
            String[]  cts = condition.split(",");
            /**
             * @param:isGroup 是否入组病例,0:否,1:是,空串:全部
             * @param isGt60 是否大于60天病例,0:否,1:是
             * @param outWay 离院方式
             * @param risk 病组风险等级
             */
            String isGroup = "-".equals(cts[0]) ? "" : cts[0];
            String isGt60 = "-".equals(cts[1]) ? "" : cts[1];
            String outWay = "-".equals(cts[2]) ? "" : cts[2];
            String risk = "-".equals(cts[3]) ? "" : cts[3];
            IndexCal index = IndexCalAssembler.toEntity(dto);
            
            //总数为0 或者 查询条件不为空 则重新获取病例总数
            if (caseTotalCount == 0 || StringUtils.hasLength(dto.getType2())) {
                caseTotalCount = drgsIndexCalApplication.findCaseCountFast(index, isGroup, isGt60, outWay, risk);
            }
          //调用新方法查询病例集合
            List<Map<String, Object>> caseMaps = drgsIndexCalApplication.findCaseListFast(page,pageSize,index,isGroup,isGt60,outWay,risk,orderColumn,orderMethod);
            
            caseListResultMaps.put("iTotalRecords", caseTotalCount);
            caseListResultMaps.put("iTotalDisplayRecords", caseTotalCount);
            caseListResultMaps.put("aaData", caseMaps);  
        }
           
        
		return InvokeResult.success(caseListResultMaps);
		
	}
	

	/**  
	 *  @Description：获取已导入病例明细
	 *  @Author mazhaoyan  
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#findImportedCaseList(com.dhcc.DRGsHosp.facade.dto.IndexCalDTO, java.lang.Boolean, int, int, int, int)  
	 */
	@Override
	public InvokeResult findImportedCaseList(String type2,String date,int page, int pageSize, int sEcho,int caseTotalCount, String orderColumn, String orderMethod) {
	    Map<String,Object> caseListResultMaps = new HashMap<String, Object>();
	    caseListResultMaps.put("sEcho",sEcho);
	    String stdId=getStdID(DrgsIndex.formateDateFrom(date),DrgsIndex.formateDateTo(date)); //获取标杆定位
	    String groupShcme=getGroupScheme();
	    //总数为0 或者 查询条件不为空 则重新获取病例总数
        if (caseTotalCount == 0||StringUtils.hasLength(type2)) {
            caseTotalCount = drgsIndexCalApplication.findImportedCaseCount(page,pageSize,date,type2,stdId,groupShcme);
        }
	    List<Map<String, Object>> caseMaps = drgsIndexCalApplication.findImportedCaseList(page,pageSize,date,type2, orderColumn, orderMethod,stdId,groupShcme);
        
        caseListResultMaps.put("iTotalRecords", caseTotalCount);
        caseListResultMaps.put("iTotalDisplayRecords", caseTotalCount);
        caseListResultMaps.put("aaData", caseMaps); 
		return InvokeResult.success(caseListResultMaps);
	}

	/**
	 * 
	 *  @Description：
	 *  @Author ZouYiyu  
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#findImportedHcCaseList(java.lang.String, java.lang.String, int, int, int, int)
	 */
	@Override
	public InvokeResult findImportedHcCaseList(String type2,String date,int page, int pageSize, int sEcho,int caseTotalCount, String orderColumn, String orderMethod) {
	    Map<String,Object> caseListResultMaps = new HashMap<String, Object>();
	    String stdId=getStdID(DrgsIndex.formateDateFrom(date),DrgsIndex.formateDateTo(date)); //获取分组方案
	    caseListResultMaps.put("sEcho",sEcho);
		String groupScheme=getGroupScheme();
	  //总数为0 或者 查询条件不为空 则重新获取病例总数
        if (caseTotalCount == 0||StringUtils.hasLength(type2)) {
            caseTotalCount = drgsIndexCalApplication.findImportedHcCaseCount(page,pageSize,date,type2,stdId,groupScheme);
        }
	    List<Map<String, Object>> caseMaps = drgsIndexCalApplication.findImportedHcCaseList(page,pageSize,date,type2, orderColumn, orderMethod,stdId,groupScheme);
        
        caseListResultMaps.put("iTotalRecords", caseTotalCount);
        caseListResultMaps.put("iTotalDisplayRecords", caseTotalCount);
        caseListResultMaps.put("aaData", caseMaps); 
		return InvokeResult.success(caseListResultMaps);
	}
	
	@Override
	public List<Object[]> releateQuotas(String quotaCode) {
		List<Object[]> quotas = drgsIndexCalApplication.getQuotas(quotaCode);
		return quotas;
	}
	/**
	 * 
	 *  @Description：获得出院病历的分组的最新日期
	 *  @Author LiuHongJun  
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getLatestDate()
	 */
	@Override
	public String getLatestDate() {
		String grupScheme=getGroupScheme();
		return drgsIndexCalApplication.getLatestDate(grupScheme);
	}
	
	/**
	 * 
	 * @methodname    :getManageSummary
	 * @description   : 获取外部标杆信息
	 * @param         :msType 标杆类型 1 绩效标杆 2 外院标杆
	 * @author        :mazhaoyan
	 * @return        :
	 * @date          :2017年6月28日
	 */
	@Override
	public InvokeResult getManageSummary(String msType) {
		return InvokeResult.success(drgsIndexCalApplication.getManageSummary(msType));
	}
	/**
	 * 
	 *  @Description：获取分组数据有哪些年份的数据
	 *  @Author LiuHongJun  
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getGroupAllYears()
	 */
	@Override
	public InvokeResult getGroupAllYears(IndexCalDTO dto) {
		List<String> years = drgsIndexCalApplication.getGroupAllYears(IndexCalAssembler.toEntity(dto));
		return InvokeResult.success(years);
	}
	/**
	 *  @desp  ： 获取分组方案
	 *  @Author： lhj
	 *  @return
	 *  @Date  :2018年1月9日上午11:28:50
	 */
	@Override
	public String  getGroupScheme() {
		String roleCode=DrgsIndex.getRoleCode();
		String userCode=CurrentUser.getUserAccount();
		if(userCode==null) {
			//接口走公共方法
			 userCode="yizheng";
		}
	    //获取分组分案cn或bj 和标杆类型 
		String mouldeId="groupScheme_"+userCode+"_"+roleCode;
		String groupSchemeBenchType = systemConfigApplication.getSystemGroupScheme(mouldeId,userCode, roleCode);
		String groupScheme=null;
	    if(StringUtils.hasLength(groupSchemeBenchType)) {
			String gbStr[]=groupSchemeBenchType.split("θ");	
			if(gbStr.length>0) {
				groupScheme=gbStr[0];
			}
		}
	    return groupScheme;
	}
	/**
	 * 
	 *  getMrDate.  
	 *  @Description：获取分组年份
	 *  @Author LiuHongjun
	 *  @return 
	 *  @Date:2017年8月7日下午3:20:48
	 */
	public Object getMrDate() {
		return drgsIndexCalApplication.getMrDate();
	}
	/**
	 *  @desp  ：获取系统折线图数据
	 *  @Author： liuhongjun
	 *  @param dto
	 *  @return
	 *  @Date  :2018年3月8日下午4:38:05
	 */
	@Override
	public InvokeResult findTrendData(IndexCalDTO dto) {
		List<Map<String, Object>> resultList = new LinkedList<>();
		ExecutorService indexPool =null;
		Future<List<Map<String, Object>>> f =null;
		/*获取首页中所有出院病历的年月*/
		List<Map<String, Object>> listTime=drgsIndexCalApplication.findMrTime();
		List<Future<List<Map<String, Object>>>> listf = new ArrayList<>();
		indexPool = Executors.newFixedThreadPool(10);
		if(!listTime.isEmpty()) {
			Map<String, Object> mapo=listTime.get(0);
			String firstTime=mapo.get("MRTIME")==null?null:mapo.get("MRTIME").toString();
			String stdId=getStdID(firstTime,firstTime);
			dto.setStdId(stdId);
			for(Map<String, Object> map:listTime){
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				qdto.setDateFrom(DrgsIndex.formateDateFrom(map.get("MRTIME").toString()));
				qdto.setDateTo(DrgsIndex.formateDateTo(map.get("MRTIME").toString()));			
				 //启动多线程
				 TrendCallable c = new TrendCallable(qdto);
				 f = indexPool.submit(c);	
				 listf.add(f);
			}
		}
		//关闭线程池
		indexPool.shutdown();
		//从future中取出数据
		for (Future<List<Map<String, Object>>> fr : listf) {
			try {
				if (fr.get().size() > 0) {
					Map<String, Object> map = fr.get().get(0);
					map.put("ddesc", map.get("dateTo").toString().substring(0,7));
					map.put("shape", "diamond");
					map.put("size", 5);
					resultList.add(map);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
	
		Collections.sort(resultList, new MapSortByField("ddesc", "asc","\\D"));
		return InvokeResult.success(resultList);
	}
	/**
	 * 
	 *  @Description：获取趋势图分析数据
	 *  @Author LiuHongJun  
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getTrendData(com.dhcc.DRGsHosp.facade.dto.IndexCalDTO)
	 */
	@Override
	public InvokeResult getTrendData(IndexCalDTO dto) {
		List<Map<String, Object>> resultList = new LinkedList<>();
		String dateFrom = DrgsIndex.formateDateFrom(dto.getDateFrom());
		String dateTo = DrgsIndex.formateDateTo(dto.getDateTo());
		String[] colors = GlobalData.colors;
		ExecutorService indexPool =null;
		Future<List<Map<String, Object>>> f =null;
		
		List<Future<List<Map<String, Object>>>> listf = new ArrayList<>();
		if("MC".equals(dto.getMrType())){
			int yearFrom = Integer.parseInt(dateFrom.substring(0, 4));
			int yearTo = Integer.parseInt(dateTo.substring(0, 4));
			indexPool = Executors.newFixedThreadPool(5);
			for(int i=0; i<5; i++){	
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				String reldateFrom = (yearFrom-i)+"-"+dateFrom.substring(5,7);
				String reldateTo = (yearTo-i)+"-"+dateTo.substring(5,7);
				qdto.setDateFrom(reldateFrom);
				qdto.setDateTo(reldateTo);	
				 //启动多线程
				 TrendCallable c = new TrendCallable(qdto);
				 f = indexPool.submit(c);	
				 listf.add(f);
			}
			//关闭线程池
			indexPool.shutdown();
			int m=0;
			//从future中取出数据
			for (Future<List<Map<String, Object>>> fr : listf) {
				try {
					if (fr.get().size() > 0) {
						Map<String, Object> map = fr.get().get(0);
						int from = Integer.parseInt(map.get("dateFrom")==null?"0":map.get("dateFrom").toString().substring(0, 4));
						int to = Integer.parseInt(map.get("dateTo")==null?"0":map.get("dateTo").toString().substring(0, 4));	
						if (from != to) {
							map.put("ddesc", from + "~" +to + "年");
						} else {
							map.put("ddesc", to + "年");
						}
						map.put("shape", "diamond");
						map.put("color", colors[m]);
						map.put("size", 5);
						resultList.add(map);
						m++;
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			}
		}else if("M".equals(dto.getMrType())){
			String mrYear = dateTo.substring(0, 4);
			indexPool = Executors.newFixedThreadPool(12);
			for(int i=1; i<13; i++){
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);
				int year = Integer.parseInt(mrYear);
				if(i<10){
					String reldateFrom =year+"-0"+i;
					String reldateTo = year+"-0"+i;
					qdto.setDateFrom(reldateFrom);
					qdto.setDateTo(reldateTo);
				}else{
					String reldateFrom =year+"-"+i;
					String reldateTo = year+"-"+i;
					qdto.setDateFrom(reldateFrom);
					qdto.setDateTo(reldateTo);
				}			
				 //启动多线程
				 TrendCallable c = new TrendCallable(qdto);
				 f = indexPool.submit(c);	
				 listf.add(f);
			}
			//关闭线程池
			indexPool.shutdown();
			int m=0;
			//从future中取出数据
			for (Future<List<Map<String, Object>>> fr : listf) {
				try {
					if (fr.get().size() > 0) {
						Map<String, Object> map = fr.get().get(0);
						map.put("ddesc", map.get("dateTo").toString().substring(5,7) + "月");
						map.put("shape", "diamond");
						map.put("color", colors[m]);
						map.put("size", 5);
						resultList.add(map);
						m++;
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			}
		}else if("custom".equals(dto.getMrType())){
			//自定义时求累计值
			int yearFrom = Integer.parseInt(dateFrom.substring(0, 4));
			int yearTo = Integer.parseInt(dateTo.substring(0, 4));
			indexPool = Executors.newFixedThreadPool(5);
			for(int m=0; m<5;m++){
				IndexCalDTO qdto=(IndexCalDTO) DrgsIndex.copyPropertiesObj(dto);	
				String reldateFrom = (yearFrom-m)+"-"+dateFrom.substring(5,7);
				String reldateTo = (yearTo-m)+"-"+dateTo.substring(5,7);
				qdto.setDateFrom(reldateFrom);
				qdto.setDateTo(reldateTo);
				 //启动多线程
				 TrendCallable c = new TrendCallable(qdto);
				 f = indexPool.submit(c);	
				 listf.add(f);
			}
			//关闭线程池
			indexPool.shutdown();
			int m=0;
			//从future中取出数据
			for (Future<List<Map<String, Object>>> fr : listf) {
				try {
					if (fr.get().size() > 0) {
						Map<String, Object> map = fr.get().get(0);	
						map.put("ddesc", map.get("dateFrom").toString().substring(0,7).replace("-",".")+"~"+map.get("dateTo").toString().substring(0,7).replace("-","."));
						map.put("shape", "diamond");
						map.put("color", colors[m]);
						map.put("size", 5);
						resultList.add(map);	
						m++;
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			}
		}
		Collections.sort(resultList, new MapSortByField("ddesc", "asc","\\D"));
		return InvokeResult.success(resultList);
	}
	/**'
	 * 
	 * @ClassName: getTrendCallable  
	 * @Description ：趋势图多线程处理    
	 * @Date: 2017年8月12日 上午11:18:38  
	 * @Author LiuHongJun 
	 * @Version 2.5.0 DHC-DRGs
	 */
	private class TrendCallable implements Callable<List<Map<String, Object>>> {
			private IndexCalDTO dto;
			TrendCallable(IndexCalDTO dto) {
				this.dto = dto;
			}
			@Override
			public List<Map<String, Object>> call() {
				List<Map<String, Object>> listMap = new ArrayList<>();
				try {
					String dateFrom=dto.getDateFrom();
					String dateTo=dto.getDateTo();
					listMap = indexCal(dto);
					if(listMap.size()>0){
						listMap.get(0).put("dateFrom", dateFrom);
						listMap.get(0).put("dateTo", dateTo);
					}
				} catch (Exception e) {
					listMap = new ArrayList<>();
					e.printStackTrace();
				}
				return listMap;
			}
		}
	/**
	 * 
	 *  @Description：监测当前分组方案以及监测时间范围内分组器版本号 
	 *  @Author lhj 
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#checkVerVersion(com.dhcc.DRGsHosp.facade.dto.IndexCalDTO)
	 */
	@Override
	public  List<Map<String, Object>>  checkVerVersion(IndexCalDTO dto) {
		String verRegion=getGroupScheme();
	    List<Map<String, Object>>  list=drgsIndexCalApplication.checkVerVersion(verRegion,DrgsIndex.formateDateFrom(dto.getDateFrom()),DrgsIndex.formateDateTo(dto.getDateTo()));
		return list;	
	}
	/**
	 *  @Description：根据医院编码获取科室组
	 *  @Author lhj 
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getDepGroupByHospCode(java.lang.String)
	 */
	@Override
	public List<Map<String, Object>>  getDepGroupByCode(String hospCode, String depGroupCode) {
		return drgsIndexCalApplication.getDepGroupByCode(hospCode,depGroupCode);
	}
	/**
	 *  @Description：根据医院编码获取病区
	 *  @Author lhj 
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getWardByHospCode(java.lang.String)
	 */
	@Override
	public List<Map<String, Object>> getWardByCode(String hospCode, String depGroupCode, String wardCode, String depCode) {
		return drgsIndexCalApplication.getWardByCode(hospCode,depGroupCode,wardCode,depCode);
	}
	/**
	 *  @Description：获取各级医师
	 *  @Author lhj 
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#getDoctor(com.dhcc.DRGsHosp.facade.dto.IndexCalDTO)
	 */
	@Override
	public List<Map<String, Object>> getDoctor(IndexCalDTO dto) {
		return drgsIndexCalApplication.getDoctor(IndexCalAssembler.toEntity(dto));
	}
	
	@Override
	public InvokeResult findCaseListGlobal(String filterStr) {
		List<Map<String, Object>> caseList = drgsIndexCalApplication.findCaseListGlobal(filterStr);
		return InvokeResult.success(caseList);
	}
	
	@Override
	public InvokeResult deleteCase(String parid) {
		try{
			drgsIndexCalApplication.deleteCase(parid);
			return InvokeResult.success();
		}catch(Exception e){
			return InvokeResult.failure(e.toString());
		}
	}
	/**
	 *  @Description：检测系统是否含有病组的绩效管理值
	 *  @Author：liuhongjun 
	 *  @see com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade#isDrgManager()
	 */
	@Override
	public boolean isDrgManager() {
		int cnt=drgsIndexCalApplication.isDrgManager();
		if(cnt>0) {
			return true;
		}
		return false;
	}

	@Override
	public String findSQLAnalysisreport(String codeSql,String templateCode,String chaper,String section) {
		return drgsIndexCalApplication.findSQLAnalysisreport(codeSql,templateCode,chaper, section);
	}
	
	@Override
	public InvokeResult getLatestPatientDate() {
		return InvokeResult.success(drgsIndexCalApplication.getLatestPatientDate());
	}


}